#include "network.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <cassert>
#include <iostream>
#include "timer.h"
#include <dirent.h>
#include <cstring>
#include "utils.h"

using namespace std;


int GetIpAddress(const char *eth, std::string& ip)
{
    int fd;
    struct ifreq ifr;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1)
    {
        perror("socket error");
        return -1;
    }

    strcpy(ifr.ifr_name, eth);
    printf("netcard name: %s\n", eth);

    if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
    {
        perror("[utils/network] ioctl");
        close(fd);
        return -1;
    }

    close(fd);

    struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr;
    char tmp[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(addr->sin_addr), tmp, INET_ADDRSTRLEN);
    ip.assign(tmp);
    return 0;
}

set<string> GetAllIfname()
{
    string ifconfigOutput = exec("ifconfig -a");
    set<string> interfaces;
    istringstream iss(ifconfigOutput);
    string line;

    while (std::getline(iss, line)) 
    {
        // 网卡名称位于行的开头，直到遇到第一个空格
        if (!line.empty() && line[0] != ' ' && line[0] != '\\t') 
        {
            istringstream lineStream(line);
            string interfaceName;
            lineStream >> interfaceName;
            interfaces.insert(interfaceName);
        }
    }

    return interfaces;
}

int JsonArraySender::send(Json::Value& rValue, const std::string&& array_key)
{
    if(!rValue.isMember(array_key) && !rValue[array_key].isArray()) return -1;
    Json::Value jArray(rValue[array_key]);
    Json::Value jPack;
    // 数组大小， 序列化消息起始位置
    int ary_size = 0, totle_size = 0;
    int pMsgSrt;

    for(auto jItem: jArray)
    {
        size_t item_size = to_string(jItem).length();
        if(item_size + ary_size > SND_HWM)
        {
            jPack["end"] = 0;
            SendMsg(jPack);
            jPack.clear();
            ary_size = 0;
        }
        jPack[array_key].append(jItem);
        ary_size += item_size;
    }
    jPack["end"] = 1;
    SendMsg(jPack);
    return 0;
}

void JsonArraySender::UnPackingSend(Json::Value &jTotal, std::string tag)
{
    finished = false;
    jTotal["end"] = 0;
    SendMsg(jTotal);
    jTotal.clear();
    // LOG_DBG("%s Message is oversize, send to client\n", tag.c_str());
}

void JsonArraySender::SendLastPackage(Json::Value& jTotal)
{
    jTotal["end"] = 1;
    SendMsg(jTotal);
    finished = true;
}

JsonArraySender::~JsonArraySender()
{
    assert(finished);
}

// void EasyOutput(Json::Value jValue)
// {
//     string jsonStr(to_string(jValue));
//     cout << jsonStr << endl;
//     cout << "json size: " << jsonStr.length() << endl;
// }

// int main(int argc, char const *argv[])
// {
//     Json::Value rValue;
//     UnPackingSender sender(EasyOutput);
//     for(int i = 0; i < 15; i ++)
//     {
//         Json::Value jItem;
//         jItem["username"] = "123";
//         jItem["password"] = "{";
//         jItem["msg"] = string(1024, '1' + i);
//         rValue["array"].append(jItem);
//     }

//     cout << to_string(rValue) << endl;

//     TIMER(
//         int size = sender.send(rValue, "array");
//         cout << "totle size: " << size << endl;
//     );
//     // cout << "resoure_size: " << to_string(rValue).length() << endl;
//     TIMER(
//     Json::Value  send;
//     for(auto jItem: rValue["array"])
//     {
//         if(sender.isOverSendBuf(send, jItem))
//         {
//             sender.UnPackingSend(send);
//         }
//         send["array"].append(jItem);
//     }
//     sender.SendLastPackage(send);
//     );


//     return 0;
// }
